//
//  main.cpp
//  balance
//
//  Created by qi mao on 7/29/12.
//  Copyright 2012 __MyCompanyName__. All rights reserved.
//

#include <iostream>
#include <fstream>
#include <cmath>
#include <iomanip>
#include "fxData.h"
#include "fxHistroy.h"
#include "highAndLow.h"
#include "timeTable.h"
using namespace std;

const int timeSeg = 51;



double findBalanceByName(class fxData data[],int size,string name);
void findHighAndLowTime(class fxData data[],int size,string name,string statistics);
void statisticsOnHighAndLowTime(string name);
int timeLookUp(string time);
string timeTick(int num);
int main ()
{

    class fxHistory fxhistroy;
    fxhistroy.initWithFilename("data.txt");


    
    //cout<<"open_balance="<<findBalanceByName(fxhistroy.Histroy,fxhistroy.period,"open")<<endl;
    //cout<<"high_balance="<<findBalanceByName(fxhistroy.Histroy,fxhistroy.period,"high")<<endl;
    //cout<<"low_balance="<<findBalanceByName(fxhistroy.Histroy,fxhistroy.period,"low")<<endl;
    //cout<<"close_balance="<<findBalanceByName(fxhistroy.Histroy,fxhistroy.period,"close")<<endl;
    
    findHighAndLowTime(fxhistroy.Histroy, fxhistroy.period,"highTimeAndLowTime.txt","statistics.txt");
    statisticsOnHighAndLowTime("highTimeAndLowTime.txt");
    char ch;
    cin.get(ch);
    return 0;
}

double findBalanceByName(class fxData data[],int size,string name){
    double min=20000;
    double max=0;
    for (int i=0;i<size;i++)
    {
        if (data[i].valueByName(name) < min) min=data[i].valueByName(name);
        if (data[i].valueByName(name) > max) max=data[i].valueByName(name);
    }
    double middle=min;
    //cout<<"max="<<max<<";min="<<min<<endl;
    double balance=0;
    int delta_min=1000;
    double inc=0.5;
    for (int j=0; j<(max-min)/inc; j++) {
        int bigger=0,smaller=0;
        
        for (int i=0;i<size;i++)
        {
            if (data[i].valueByName(name) > middle) bigger++;
            if (data[i].valueByName(name) < middle) smaller++;
        }
        //cout<<abs(bigger-smaller)<<endl;
        if (abs((double)bigger-smaller)<delta_min) {
            delta_min=abs((double)bigger-smaller);
            balance=middle;
            //cout<<abs(bigger-smaller)<<endl;
            //cout <<delta_min<<endl;
        }
        middle=middle+inc;
    }
    return balance;
}

void findHighAndLowTime(class fxData data[],int size,string name,string statistics){
    //cout<<"hello"<<endl;
    
    /*
    const int timeSeg = 48;
    string timeTick[timeSeg]={"0:00","0:30","1:00","1:30","2:00","2:30","3:00","3:30","4:00","4:30","5:00","5:30","6:00","6:30","7:00","7:30","8:00","8:30","9:00","9:30","10:00","10:30","11:00","11:30","12:00","12:30","13:00","13:30","14:00","14:30","15:00","15:30","16:00","16:30","17:00","17:30","18:00","18:30","19:00","19:30","20:00","20:30","22:00","22:30","23:00","23:15","23:30","23:45"};
    */
    
    
    string firstDay=data[0].day; //程序依次向后推进
    double max=0;double min=20000;
    string highTime,lowTime;
    ofstream ofile;
    ofile.open(name.c_str());
    ofstream ofile2;
    ofile2.open(statistics.c_str());
    char ud;//向上或者向下的标记，向上为+，向下为-,十字位*
    double ud_open,ud_close;
    int ud_open_mark,ud_close_mark,hourCount;
    ud_open_mark=0;ud_close_mark=0;
    ud_open=0;ud_close=0;hourCount=0;
    
    double halfHourUp[timeSeg]={0};
    double halfHourDown[timeSeg]={0};
    double halfHourStar[timeSeg]={0};
    double halfHourNum[timeSeg]={0};
    double totalUpOrDown[timeSeg]={0};
    double sumUpOrDown[timeSeg]={0};
    
    for (int i=0; i<size; i++) {
        if (firstDay == data[i].day) {
            
            if (data[i].high > max) {
                max = data[i].high;
                highTime = data[i].time;
            }
            if (data[i].low < min) {
                min = data[i].low;
                lowTime = data[i].time;
            }
            if (ud_open_mark==0) {
                ud_open = data[i].open;
                ud_open_mark = 1;
            }//用第一次读取的作为open
            if (firstDay!=data[i+1].day) {
                ud_close = data[i].close;
            }//用day变化的上一次作为close
            hourCount++;

            
        } else {
            if (ud_close > ud_open) {
                ud='+';
            } else {
                ud='-';
            }
            //cout<<hourCount<<endl;
            ofile2<<firstDay<<"\t";
            double upCount=0;
            double downCount=0;
            for (int k=i-hourCount; k<i; k++) {
                //cout<<'*';
                if (fabs(data[k].close - data[k].open)< 0.5) {
                    //cout<<'*';
                } else if (data[k].close > data[k].open){
                    //cout<<'+';
                    upCount++;
                }else {
                    //cout<<'-';
                    downCount++;
                }
            }
            upCount=upCount/(timeSeg-1)*100;
            downCount=downCount/(timeSeg-1)*100;
            double amp=fabs(ud_close-ud_open);
            ofile2<<ud<<amp/*<<"\t"<<ud_open<<"\t"<<ud_close<<"\t"<<"\t"*/<<"\t"<<fixed<<setprecision(2)<<upCount<<"\t"<<downCount<<"\t";
            //cout<<setprecision(6);
            //cout<<"\t"<<ud<<"\t"<<amp<<endl;
            
            
            for (int k=i-hourCount; k<i; k++) {
                
                halfHourNum[timeLookUp(data[k].time)]++;
                if (fabs(data[k].close - data[k].open)> 0.5){
                    totalUpOrDown[timeLookUp(data[k].time)]+=(data[k].close-data[k].open);
                    sumUpOrDown[timeLookUp(data[k].time)]+=(fabs(data[k].close-data[k].open));
                }
                
                if (fabs(data[k].close - data[k].open)< 0.5) {
                    ofile2<<'*';
                    halfHourStar[timeLookUp(data[k].time)]++;
                } else if (data[k].close > data[k].open){
                    ofile2<<'+';
                    halfHourUp[timeLookUp(data[k].time)]++;
                }else {
                    ofile2<<'-';
                    halfHourDown[timeLookUp(data[k].time)]++;
                }
            }
            ofile2<<endl;
            ofile<<firstDay<<"\t"<<highTime<<"\t"<<max<<"\t"<<lowTime<<"\t"<<min<<"\t"<<ud<<endl;
            firstDay=data[i].day;
            ud_open_mark=0;
            i--;
            max = 0;min = 20000;ud_close=0;ud_open=0;hourCount=0;
        }
        } 
    ofile.close();
    
    for (int i=0; i<timeSeg; i++) {
        halfHourUp[i]/=halfHourNum[i];
        halfHourDown[i]/=halfHourNum[i];
        halfHourStar[i]/=halfHourNum[i];
        sumUpOrDown[i]=totalUpOrDown[i]/sumUpOrDown[i]*100;
        ofile2<<timeTick(i)<<"\t"<<halfHourUp[i]<<"\t"<<halfHourDown[i]<<"\t"<<halfHourStar[i]<<"\t"<<totalUpOrDown[i]<<"\t"<<sumUpOrDown[i]<<endl;
    }
    ofile2.close();
    
}

void statisticsOnHighAndLowTime(string name){
    ifstream ifile(name.c_str());
    class highAndLow HL[60000];
    int period=0;
    for (int i=0;i<60000;i++) {
        for (int j=0; j<6; j++) {
            switch (j) {
                case 0:
                    ifile>>HL[i].day;
                    break;
                case 1:
                    ifile>>HL[i].highTime;
                    break;
                case 2:
                    ifile>>HL[i].highValue;
                    break;
                case 3:
                    ifile>>HL[i].lowTime;
                    break;
                case 4:
                    ifile>>HL[i].lowValue;
                    break;
                case 5:
                    ifile>>HL[i].ud;
                    break;
                default:
                    break;
            }
            //if (Histroy[i].high==0) break;
        }
        //Histroy[i].print();
        if (HL[i].highValue==0) break;
        period++;
        HL[i].print();
        
        
        
    }
    cout<<"period="<<period<<endl;
    /*
    const int timeSeg = 48;
    string timeTick[timeSeg]={"0:00","0:30","1:00","1:30","2:00","2:30","3:00","3:30","4:00","4:30","5:00","5:30","6:00","6:30","7:00","7:30","8:00","8:30","9:00","9:30","10:00","10:30","11:00","11:30","12:00","12:30","13:00","13:30","14:00","14:30","15:00","15:30","16:00","16:30","17:00","17:30","18:00","18:30","19:00","19:30","20:00","20:30","22:00","22:30","23:00","23:15","23:30","23:45"};
     */
    int highTimeStat[timeSeg]={0},lowTimeStat[timeSeg]={0};
    for (int i=0; i<timeSeg; i++) {
        for (int j=0; j<period; j++) {
            if (HL[j].highTime==timeTick(i)) {
                highTimeStat[i]++;
            }
            if (HL[j].lowTime==timeTick(i)) {
                lowTimeStat[i]++;
            }
        }
    }
    double highPossibility,lowPossibility;
    
    for (int i=0; i<timeSeg; i++) {
        highPossibility = (double)highTimeStat[i]*100/period;
        lowPossibility = (double)lowTimeStat[i]*100/period;
        cout<<timeTick(i)<<"\t";
        //cout<<highTimeStat[i];
        //cout<<"\t";
        cout<<setprecision(2)<<highPossibility;
        cout<<"\t";
        //cout<<lowTimeStat[i];
        //cout<<"\t";
        cout<<setprecision(2)<<lowPossibility<<endl;
    }
    
    ifile.close();
}

int timeLookUp(string time){
    
    int i=0;
    for (i=0; i<timeSeg; i++) {
        if (timeTick(i)==time) {
            
            break;
        }
    }
    return i;
    //cout<<time<<"\t";
    //return timeSeg;
    
}

string timeTick(int num){
    
    string timetick[timeSeg]={"0:00","0:30","1:00","1:30","2:00","2:30","3:00","3:30","4:00","4:30","5:00","5:30","6:00","6:30","7:00","7:30","8:00","8:30","9:00","9:30","10:00","10:30","11:00","11:30","12:00","12:30","13:00","13:30","14:00","14:30","15:00","15:30","16:00","16:30","17:00","17:30","18:00","18:30","19:00","19:30","20:00","20:30","21:00","21:30","22:00","22:45","22:30","23:00","23:15","23:30","23:45"};
    return timetick[num];

}



